Open source · Apache 2.0

Secure sandbox for AI coding agents

Docker keeps an agent in — it doesn't stop it from running terraform destroy with your credentials. Agent Cerberus adds the missing half.

git clone https://github.com/shkrwnd/agent-cerberus && cd agent-cerberus && ./start.sh

Agent=Sandbox+Authorization
The sandbox keeps an agent contained. But containment alone is not enough — an agent with your AWS credentials can still delete a production database from inside a container. Authorization ensures every action is checked against policy before it runs, on the host, where the agent can't tamper with it.

CLI interception

Shell wrappers replace aws, git, kubectl, terraform, and more inside the container. Claude Code sees real CLIs — they're shims that serialize every call as JSON and send it to the host.

🔒

Host-side execution

The execution server runs on the host with real credentials. A pluggable auth backend decides approve/deny per command. The container never sees tokens, keys, or the policy itself.

🌐

Network control

The container sits on an internal: true Docker network with no internet. A tinyproxy sidecar allowlists domains. DNS goes through dnsmasq. Exfiltration is blocked at the network layer.


How it works

Every CLI call from the agent follows the same path: wrapper → agent-exec → sidecar relay → host execution server → auth backend → real binary (or denial).

Agent Cerberus architecture — agent container, sidecar, and host execution server

What happens when Claude runs aws s3 ls

  1. Claude Code calls /opt/agent/bin/aws — a shell wrapper, not the real AWS CLI
  2. The wrapper invokes agent-exec, which POSTs {"tool":"aws","args":["s3","ls"]} to the sidecar
  3. Sidecar relays the request to the host execution server via socat
  4. Host verifies the shared token, calls the configured auth backend
  5. If approved: runs the real aws with host credentials, returns stdout/stderr
  6. If denied: returns an error. The real CLI never executes.

Network layout

  1. Container on a Docker internal: true network — no route to the internet
  2. All HTTPS through the sidecar's tinyproxy, which checks domains against an allowlist
  3. DNS forwarded by dnsmasq (internal networks block external DNS)
  4. Node.js doesn't natively use HTTPS_PROXY — a bootstrap script patches the global HTTP agents at startup
claude > I'll check the deployment and clean up old infra. → broker kubectl get pods -n prod APPROVED static_policy · 12ms → broker terraform destroy -auto-approve DENIED destructive operation blocked by policy → broker git push --force origin main DENIED force push is on the deny list

Defense in depth

Every layer is designed so that bypassing the sandbox gains nothing. The execution server authorizes on the host using policy the container cannot see or influence.

Credential isolation

No ~/.aws, ~/.ssh, ~/.kube, or Docker config inside the container. Credentials are injected per-command by the host-side auth backend.

Pluggable authorization

Static allow/deny lists, webhooks, OPA, or your own Python class. Switch backends in server.env without rebuilding.

Egress filtering

Internal Docker network with a tinyproxy sidecar. Only allowlisted domains are reachable. Token exfiltration blocked at network layer.

Audit trail

Every command logged with tool, args, auth decision, exit code, and duration. Logged on the host, not inside the container.

Container hardening

cap_drop: ALL, no-new-privileges, seccomp profile, memory and pid limits, non-root user (UID 1000).

Loopback only

Execution server binds 127.0.0.1. Container reaches it via socat relay in the sidecar. Never exposed to the network.


Containment is only half the system
ControlPlain DockerOther SolutionsAgent Cerberus
Process / filesystem isolationIncludedIncludedHardened
Credentials outside guestUsually mountedEnv vars passedAlways isolated
Per-command authorizationNonePrompt onlyPluggable backends
Domain-filtered egressManual iptablesAll-or-nothingAllowlist proxy
Central audit trailContainer logsNoneDecision-level
Container hardeningUser configMinimalseccomp + caps + non-root

Up and running in five minutes

Docker and Git are the only requirements. Claude Code is installed inside the image.

Supported tools: aws, az, gh, git, kubectl, psql, terraform — adding more is a three-line wrapper. Open an issue to request one.
1
Clonegit clone https://github.com/shkrwnd/agent-cerberus.git
cd agent-cerberus
2
Mount your workspaces# deploy/docker-compose.override.yml
services:
claude:
volumes:
- /path/to/project:/workspace/project:rw
3
Set an auth policy# deploy/server.env
AUTH_BACKEND=server.auth_backends.static_policy.StaticPolicyBackend
4
Start./start.sh